///定义一个Dart类 ， 所有得类都继承自Object



class Student extends Person{
  //定义类的变量 通过下划线 来表示 私有变量 和私有方法 ，在其他文件访问不到
  String _school;
  String city;
  String country;
  String name;
  ///构造方法
  ///初始化自身的参数 通过this._scholl 初始化自由参数
  ///：后面的表达式 是 类的初始化列表
  ///{}里面定为可选参数 {this.city } 默认参数{this.country="china"}
  Student(this._school ,String name, int age ,
      {this.city ,this.country="china"})
      : //初始化列表：除了调用父类构造器 ，在子类构造器 方法体之前，你也可以初始化实例变量，不同的初始化变量之间用逗号分割开
     this. name = name,
  //父类的构造方法  如果父类没有默认的构造方法（无参的构造方法） ，则需要在初始列表中调用父类的构造方法进行初始化。
        super(name, age){
    //构造方法 方法体 打印一句话 初始化操作等 ，构造方法提不是必须的 ，可有可无
    print("构造方法提不是必须的");
  }



  //私有变量 get方法
  String get school =>_school;


  set school(String value) {
    _school = value;
  }


  @override
  String toString() {
    return "name : $name school : ${this._school} , city : $city country : $country , ${super.toString()}";
  } //静态方法
  static doPrict(String str){
    print("doPrict$str");
  }


  ///命名构造方法
  ///类+.+方法名
  ///使用命名构造方法为类实现多个构造方法
  Student.cover(Student stu):super(stu.name , stu.age){
    print("命名构造方法");
  }
}

class Logger{
  static  Logger _cache;
  ///工厂构造方法
  ///不仅仅是构造方法 ，更是一种模式
  ///有时候为了返回一个之前已经创建的缓存对象，原始的构造方法已经不能满足要求了
  ///那么可以使用工厂模式来 定义构造方法

  factory Logger(){
    if(_cache == null){
      _cache = Logger._internal();
    }
    return _cache;
  }

  Logger._internal();
}


class Person{
  String name;
  int age;

  ///类构造方法 初始化类的变量
  ///最普通初始化方法 最标准的构造方法
  Person(this.name , this.age);


  ///多态的多种表现就是重载  重写父类的方法
  @override
  String toString() {
    return 'Person{name: $name, age: $age}';
  }

}

///继承抽象类 必须实现抽象类里面 的方法 ， 否则也需要将自己定义成抽象类
class StudyFlutter extends Study{
  @override
  void study() {
    print("学习flutter");
  }

}

///使用abstract 修饰符来定义一个抽象类， 该类不能被实例话，抽象类在定义借口的时候 非常有用
abstract class Study{
  //可以有抽象方法 也可以没有 如果一个类有抽象方法 ，那她必须是抽象类
  void study();
}

///为类添加特征 ：mixins
///mixins 是在多个类层次结构中重用代码的一种方式
///要是用mixins ，我们需要在 with关键字后面 跟上一个 或者 多个 mixins 的名字 ，多个我们要用 逗号分隔 ，with要在extents之后
class Test extends Person with Study{
  Test(String name, int age) : super(name, age);

  @override
  void study() {
    // TODO: implement study
  }

}